﻿using System;
using System.IO;
using System.Reflection;
using System.Xml;

namespace NuGet.Versioner
{
	class Program
	{
		static void Main(string[] args)
		{
			try
			{
				if (args.Length != 1)
				{
					Console.WriteLine("Usage: NuGetVersioner.exe <NuspecFileName>");
					return;
				}

				string fullPath = args[0];

				if (String.IsNullOrEmpty(Path.GetDirectoryName(fullPath)))
				{
					string fileName = fullPath;

					fullPath = Path.Combine(Environment.CurrentDirectory, fileName);

					if (!File.Exists(fullPath))
					{
						Console.WriteLine("NuGet.Versioner cannot find '{0}'.", fileName);
						Environment.Exit(-1);
					}
				}

				UpdateVersion(fullPath);
			}
			catch (Exception)
			{
				Console.WriteLine("Updating version failed.");
				Environment.Exit(-1);
			}
		}

		private static void UpdateVersion(string fullPath)
		{
			Console.WriteLine("Attempting to inspect '{0}' for existing version.", fullPath);

			XmlDocument doc = new XmlDocument();
			doc.Load(fullPath);
			XmlNodeList nodes = doc.GetElementsByTagName("version");

			if (nodes.Count == 1)
			{
				if (String.IsNullOrEmpty(nodes[0].InnerText))
				{
					string version = GetVersion(Path.GetDirectoryName(fullPath), doc);

					Console.WriteLine("Attempting to update version and save.");
					nodes[0].InnerText = version;

					doc.Save(fullPath);
					Console.WriteLine("Successfully updated version in '{0}'.", fullPath);
					return;
				}
			}

			Console.WriteLine("Version already specified in '{0}'...skipping update.", fullPath);
		}

		private static string GetVersion(string path, XmlDocument doc)
		{
			XmlNodeList files = doc.GetElementsByTagName("file");
			foreach (XmlNode file in files)
			{
				if (file.Attributes.Count > 0)
				{
					XmlAttribute attribute = file.Attributes["src"];

					if (attribute.Value.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) || attribute.Value.EndsWith(".exe", StringComparison.OrdinalIgnoreCase))
					{
						string fullPath = Path.Combine(path, attribute.Value);

						Console.WriteLine(String.Format("Attempting to extract version from '{0}'.", fullPath));
						Assembly assembly = Assembly.LoadFile(fullPath);
						return assembly.GetName().Version.ToString();
					}
				}
			}

			return String.Empty;
		}

	}
}